﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Frogger
{
    abstract class Entity
    {
        /*******************************************/
        private bool __visible = true;
        /********************************************/
        //Basic fields
        protected Texture2D __textureImage;
        protected Vector2 __position;
        protected Point __frameSize;
        protected int __collisionOffset;
        protected Point __currentFrame;
        protected Point __sheetSize;
        protected int __timeSinceLastFrame = 0;
        protected int __millisecondsPerframe;
        const int __defaultMillisecondsPerframe = 16;

        //Scale
        protected float __scale = 1;
        protected float __originalScale = 1;

        public float Scale
        {
            get;
            protected set;
        }

        //Scoring
        public int scoreValue
        {
            get;
            protected set;
        }

        //Name for different score font
        public string Name 
        { 
            get; 
            private set; 
        }
        

        public abstract Rectangle collisionRect
        {
            get;
        }

        //Constructors
        public Entity(Texture2D textureImage, Vector2 position, Point frameSize,
            int collisionOffset, Point currentFrame, Point sheetSize,
            int millisecondsPerFrame, string name, int scoreValue)
        { 
            this.__textureImage = textureImage;
            this.__position = position;
            this.__frameSize = frameSize;
            this.__collisionOffset = collisionOffset;
            this.__currentFrame = currentFrame;
            this.__sheetSize = sheetSize;
            this.__millisecondsPerframe = millisecondsPerFrame;
            this.Name = name;
            this.scoreValue = scoreValue;
        }

        public Entity(Texture2D textureImage, Vector2 position, Point frameSize,
            int collisionOffset, Point currentFrame, Point sheetSize,
            string name, int scoreValue)
            : this(textureImage, position, frameSize, collisionOffset, currentFrame,
            sheetSize, __defaultMillisecondsPerframe, name, scoreValue)
        {
        }

        public Entity(Texture2D textureImage, Vector2 position, Point frameSize,
            int collisionOffset, Point currentFrame, Point sheetSize,
            string name, int scoreValue, float scale)
            : this(textureImage, position, frameSize, collisionOffset, currentFrame,
            sheetSize, __defaultMillisecondsPerframe, name, scoreValue)
        {
            this.__scale = scale;
            this.__originalScale = scale;
        }

        public virtual void Update(GameTime gameTime, Rectangle clientBounds)
        {
            
        }

/****************************************************************************************/
        public virtual void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            //Draw the sprite
            if(visible)
            {
                //spriteBatch.Draw(this.__textureImage,
                  //  this.__position,
                    // null, Color.White, 0, Vector2.Zero,
                    //this.__scale, SpriteEffects.None, 0);
                    spriteBatch.Draw(this.__textureImage,
                        this.__position,
                        new Rectangle(this.__frameSize.X * this.__currentFrame.X,
                            this.__frameSize.Y * this.__currentFrame.Y,
                            this.__frameSize.X, this.__frameSize.Y),
                            Color.White, 0, Vector2.Zero,
                            this.__scale, SpriteEffects.None, 0);
                }
        }
/********************************************************************************************/
        //Check if the sprite is not of bounds
        public bool IsOutOfBounds(Rectangle clientRect)
        {
            if (this.__position.X < -this.__frameSize.X ||
            this.__position.X > clientRect.Width ||
            this.__position.Y < -this.__frameSize.Y ||
            this.__position.Y > clientRect.Height)
            {
                return true;
            }
            return false;
        }

        //Getters and Setters
        public Vector2 GetPosition
        {
            get 
            { 
                return this.__position; 
            }
        }

        public void ModifyScale(float modifier)
        {
            this.__scale *= modifier;
        }

        public void ResetScale()
        {
            this.__scale = this.__originalScale;
        }

        /**************************************************************/
        public Point GetFrameSize()
        {
            return __frameSize;
        }

        public Point GetCurrentFrame()
        {
            return __currentFrame;
        }

        public void SetCurrentFrame(Point cf)
        {
            __currentFrame = cf;
        }

        public void SetVisible(bool v)
        {
            __visible = v;
        }
        public bool GetVisible()
        {
            return __visible;
        }
        public void SetPosition(Vector2 pos)
        {
             __position = pos;
        }
/**********************************************************************/
        
    }
}
